/*
 * Copyright 2016-2019 yoara
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package yhao.infra.feature.payment.core.wxpay.config;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;

import javax.net.ssl.SSLContext;
import java.io.InputStream;
import java.security.KeyStore;

/**
 * 微信支付配置生成类
 *
 * @author yoara
 */
public class WinXinConfig{
    // 这个就是自己要保管好的私有Key了（切记只能放在自己的后台代码里，不能放在任何可能被看到源代码的客户端程序中）
    // 每次自己Post数据给API的时候都要用这个key来对所有字段进行签名，生成的签名会放在Sign这个字段，API收到Post数据的时候也会用同样的签名算法对Post过来的数据进行签名和验证
    // 收到API的返回的时候也要用这个key来对返回的数据算下签名，跟API的Sign数据进行比较，如果值不一致，有可能数据被第三方给篡改
    private String partner_key;

    //微信分配的公众账号ID（企业号corpid即为此appId）
    private String app_id;
    //微信支付分配的商户号
    private String partner_id;
    private String notify_url_pre;
    private String wap_url;//WAP站的地址
    private String wap_name;//WAP站的地址
    private String uniform_order_url;//统一下单url
    private String refund_url;//退款url
    private String refund_query_url;//退款查询url
    private String pay_query_url;//交易查询url
    private String credentials_name;//证书路径
    private String redirect_url;//H5支付后跳转页面

    public CloseableHttpClient httpclient;//有证书客户端,退款用
    //请求器的配置
    private RequestConfig requestConfig;

    //连接超时时间，默认10秒
    private int socketTimeout = 10000;

    //传输超时时间，默认30秒
    private int connectTimeout = 30000;

    private WinXinConfig(){}

    public static WinXinConfig generateConfig(String app_id,String partner_id,String partner_key,String notify_url_pre,
                  String wap_url,String wap_name,String uniform_order_url,String refund_url,
                  String refund_query_url,String redirect_url,String credentials_name,String pay_query_url) throws Exception {
        WinXinConfig config = new WinXinConfig();
        config.app_id = app_id;
        config.partner_id = partner_id;
        config.partner_key = partner_key;
        config.notify_url_pre = notify_url_pre;
        config.wap_url = wap_url;
        config.wap_name = wap_name;
        config.uniform_order_url = uniform_order_url;
        config.refund_url = refund_url;
        config.refund_query_url = refund_query_url;
        config.redirect_url = redirect_url;
        config.credentials_name = credentials_name;
        config.pay_query_url = pay_query_url;

        if (StringUtils.isNotBlank(config.refund_url) && StringUtils.isNotBlank(config.credentials_name)) {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            InputStream inStream = WinXinConfig.class.getClassLoader().getResourceAsStream(config.credentials_name);
            try {
                // 这里就指的是KeyStore库的密码
                keyStore.load(inStream, config.partner_id.toCharArray());
            } finally {
                inStream.close();
            }
            SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, partner_id.toCharArray()).build();
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1"}  // supportedProtocols ,这里可以按需要设置
                    , null  // supportedCipherSuites
                    , SSLConnectionSocketFactory.getDefaultHostnameVerifier());
            config.httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        }
        config.requestConfig = RequestConfig.custom().
                setSocketTimeout(config.socketTimeout).setConnectTimeout(config.connectTimeout).build();
        return config;
    }

    public String getWap_url() {
        return wap_url;
    }

    public String getRedirect_url() {
        return redirect_url;
    }

    public String getPay_query_url() {
        return pay_query_url;
    }

    public String getUniform_order_url() {
        return uniform_order_url;
    }

    public CloseableHttpClient getHttpclient() {
        return httpclient;
    }

    public String getRefund_url() {
        return refund_url;
    }

    public String getRefund_query_url() {
        return refund_query_url;
    }

    public String getWap_name() {
        return wap_name;
    }

    public String getApp_id() {
        return app_id;
    }

    public String getPartner_id() {
        return partner_id;
    }

    public String getPartner_key() {
        return partner_key;
    }

    public String getNotify_url_pre() {
        return notify_url_pre;
    }

    public RequestConfig getRequestConfig() {
        return requestConfig;
    }

}
